/*
 * Copyright 2011-2012 by The Regents of the University of California Licensed
 * under the Apache License, Version 2.0 (the "License"); you may not use this
 * file except in compliance with the License. you may obtain a copy of the
 * License from
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */
package edu.ucsd.db.bassarisk.storage.columns;

import java.nio.ByteBuffer;

import edu.ucsd.db.bassarisk.data.values.LongType;
import edu.ucsd.db.bassarisk.data.values.LongType.LongTools;
import edu.ucsd.db.bassarisk.storage.common.ColumnStore;
import edu.ucsd.db.bassarisk.storage.loading.CabinetLoader;
import edu.ucsd.db.bassarisk.storage.loading.ColumnLoader;
import edu.ucsd.db.bassarisk.storage.loading.ColumnSegmentInfo;
import edu.ucsd.db.bassarisk.storage.loading.DrawerLoader;
import edu.ucsd.db.bassarisk.storage.loading.ICardLoader;
import edu.ucsd.db.bassarisk.storage.loading.IColumnIndexer;
import edu.ucsd.db.bassarisk.storage.loading.IDrawerIndexer;
import edu.ucsd.db.bassarisk.storage.loading.VariableLengthLongCardLoader;
import edu.ucsd.db.bassarisk.storage.loading.VariableLengthLongColumnIndexer;
import edu.ucsd.db.bassarisk.storage.loading.VariableLengthLongDrawerIndexer;
import edu.ucsd.db.bassarisk.storage.reading.CabinetReader;
import edu.ucsd.db.bassarisk.storage.reading.ColumnReader;
import edu.ucsd.db.bassarisk.storage.reading.DrawerReader;
import edu.ucsd.db.bassarisk.storage.reading.ICardReader;
import edu.ucsd.db.bassarisk.storage.reading.IColumnIndexReader;
import edu.ucsd.db.bassarisk.storage.reading.IDrawerIndexReader;
import edu.ucsd.db.bassarisk.storage.reading.VariableLengthLongCardReader;
import edu.ucsd.db.bassarisk.storage.reading.VariableLengthLongColumnIndexReader;
import edu.ucsd.db.bassarisk.storage.reading.VariableLengthLongDrawerIndexReader;

public class VariableLengthUnsignedLongColumnFactory implements
    IColumnFactory<LongType> {

  @Override
  public ColumnLoader<LongType> makeColumnLoader(final CabinetLoader cabinetLoader,
                                                 final String columnKey) {
    // Prepare injected dependencies
    ICardLoader<LongType> cardLoader = new VariableLengthLongCardLoader();
    ByteBuffer drawerBuffer = ByteBuffer.allocate(ColumnStore.BYTES_IN_DRAWER);
    IDrawerIndexer<LongType> drawerIndexer = new VariableLengthLongDrawerIndexer();
    ColumnSegmentInfo<LongType> drawerInfo =
        new ColumnSegmentInfo<LongType>(LongTools.INSTANCE);
    DrawerLoader<LongType> drawerLoader =
        new DrawerLoader<LongType>(drawerIndexer, drawerInfo, drawerBuffer);
    IColumnIndexer<LongType> columnIndexer = new VariableLengthLongColumnIndexer();
    ColumnSegmentInfo<LongType> columnInfo =
        new ColumnSegmentInfo<LongType>(LongTools.INSTANCE);

    // Create loader
    ColumnLoader<LongType> cLoader =
        new ColumnLoader<LongType>(cabinetLoader, cardLoader, drawerLoader,
                                   columnIndexer, columnInfo, columnKey);
    return cLoader;
  }

  @Override
  public ColumnReader<LongType> makeColumnReader(final CabinetReader cabinetReader,
                                                 final int columnHeaderAddress) {
    // Prepare injected dependencies
    ICardReader<LongType> cardReader = new VariableLengthLongCardReader();
    IDrawerIndexReader<LongType> drawerIndexReader =
        new VariableLengthLongDrawerIndexReader();
    DrawerReader<LongType> drawerReader =
        new DrawerReader<LongType>(cardReader, drawerIndexReader, LongTools.INSTANCE);
    IColumnIndexReader<LongType> columnIndexReader =
        new VariableLengthLongColumnIndexReader();

    // Create reader
    ColumnReader<LongType> cReader =
        new ColumnReader<LongType>(drawerReader, columnIndexReader,
                                   LongTools.INSTANCE);
    cReader.initialize(cabinetReader, columnHeaderAddress, LongTools.INSTANCE);
    return cReader;
  }

}
